package org.skyui.controllers;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.skyui.accesscontrol.HumanAuthenticator;
import org.skyui.annotations.SkyTab;
import org.skyui.beanmanagers.BeanSetManager;
import org.skyui.beans.AbstractBean;
import org.skyui.beans.NewsBean;
import org.skyui.config.NavigationConfig;
import org.skyui.core.AccessControl;
import org.skyui.core.Menu;
import org.skyui.core.NavigationTree;
import org.skyui.core.UIApplication;
import org.skyui.views.ExistingBeanView;
import org.skyui.views.ExistingBeansTableView;
import org.skyui.views.NavigationTabSheet;
import org.skyui.views.NewsView;
import org.skyui.views.UIView;

import com.baycrypt.server.beans.people.UserBean;
import com.baycrypt.vaadinui.VaadinUIApplication;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.AbstractSelect;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.Select;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.Table;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;

public class NavigationController implements Select.ValueChangeListener {

    /**
	 * 
	 */
    private static final long serialVersionUID = 6435962620179528726L;

    private NavigationTree tree;
    private Table table;
    private TabSheet ts;

    private NavigationConfig navigationConfig;

    public NavigationController(Class navigationClass) {
	ts = new NavigationTabSheet();
	this.navigationConfig = new NavigationConfig(navigationClass);
	for (Menu menuItem : navigationConfig.getMenuItems()) {
	    this.menusMap.put(menuItem.getName(), menuItem);
	}
    }

    public TabSheet getNavigationTabSheet() {
	return this.ts;
    }

    private Map<String, Menu> menusMap = new HashMap<String, Menu>();

    private Menu getMenu(String name) {
	return this.menusMap.get(name);
    }

    public void destroyAndCreateTabs() {

	final Object id = table.getValue();
	if (id == null) {
	    return;
	}
	final Item item = table.getItem(id);

	final String menuName = (String) item.getItemProperty(CAPTION_PROPERTY)
		.getValue();
	if (menuName == "")
	    return;

	if (menuName.equals("Logout")) {
	    UserBean user = (UserBean) UIApplication.getInstance().getUser();
	    HumanAuthenticator.deauthenticateUser(user);
	    new NewsBean(user, null, null, "UI", "LOGOUT", "logged out",
		    NewsBean.PRIORITY_NORMAL, user.getOrganization())
		    .createPersist();
	    VaadinUIApplication.getInstance().getMainWindow()
		    .removeAllComponents();
	    VaadinUIApplication.getInstance().close();
	    return;
	}
	ts.removeAllComponents();

	if (menuName.equals("News")) {
	    NewsView nw = new NewsView();
	    ts.addTab(nw, nw.getName(), null);
	    return;
	}

	Menu m = getMenu(menuName);
	SkyTab[] tabs = m.getTabs();
	for (SkyTab tab : tabs) {
	    if (!AccessControl.isAccessible(tab.roles(), tab.productEditions(),
		    UIApplication.getInstance()))
		continue;

	    
	    Component cmp;

	    try {

		BeanSetManager mgr = BeanSetManager
			.getManagerFromUserSession(tab.beanClass());

		if ((AccessControl.isSingleton(tab.beanClass(),
			UIApplication.getInstance()))
			&& (mgr.getRefreshedBeansAsList().size() > 0)) {

		    cmp = new ExistingBeanView(
			    tab.name(),
			    tab.description(),
			    (AbstractBean) mgr.getRefreshedBeansAsList().get(0),
			    UIApplication.getInstance());

		    System.out.println("1");
		} else {
		    cmp = new ExistingBeansTableView(tab.name(),
			    tab.description(), tab.showTableCaptions(), mgr);
		    System.out.println("2");
		}

	    } catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		continue;
	    }

	    ts.addTab(cmp, ((UIView) cmp).getName(), null);
	}
    }

    // Property IDs
    public static final String CAPTION_PROPERTY = "CAPTION_NAME";
    public static final String IMAGE_PROPERTY = "IMAGE_NAME";

    private void addNavigationButton(VerticalLayout vl, String name) {
	Button b = new Button(name);
	b.setStyle(Button.STYLE_LINK);
	b.setHeight("40px");
	b.setWidth("200px");
	vl.addComponent(b);
	vl.setComponentAlignment(b, Alignment.TOP_CENTER);
    }

    public Table initializeMenuTable(UIApplication application) {

	Container container = new HierarchicalContainer();

	container.addContainerProperty(CAPTION_PROPERTY, String.class, "");
	container.addContainerProperty(IMAGE_PROPERTY, Resource.class, null);

	Object newsid = container.addItem();
	initItem(container.getItem(newsid), "News", null);

	Object id;
	for (Menu m : this.navigationConfig.getMenuItems()) {
	    if (!AccessControl.isAccessible(m, UIApplication.getInstance()))
		continue;
	    id = container.addItem();
	    initItem(container.getItem(id), m.getName(), m.getIcon());
	}

	id = container.addItem();
	initItem(container.getItem(id), "Logout", null);

	this.table = new Table("", container);
	table.setStyleName("borderless");
	table.setSelectable(true);
	table.setMultiSelect(false);
	table.setSortDisabled(true);
	table.setSizeFull();
	table.setImmediate(true);
	table.setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
	table.setVisibleColumns(new Object[] { CAPTION_PROPERTY });
	table.addListener(this);
	table.setValue(newsid);
	destroyAndCreateTabs();
	this.ts.requestRepaint();
	return table;
    }

    private static void initItem(Item item, String caption, ThemeResource icon) {
	Property prop = item.getItemProperty(CAPTION_PROPERTY);
	prop.setValue(caption);
	prop = item.getItemProperty(IMAGE_PROPERTY);
	prop.setValue(icon);
    }

    public void valueChange(ValueChangeEvent event) {
	if (event.getProperty() == this.table) {
	    destroyAndCreateTabs();
	}
    }

}
